---
title: 使用反射在运行时分析对象
---
利用反射机制可以查看在编译时还不知道的对象字段，要做到这一点，关键方法是 Field 类中的 get 方法。

如果 f 是一个 Field 类型的对象（例如通过 getDeclaredFields 的到的对象），obj 是某个包含 f 字段的类的对象，则 f.get(obj) 将返回一个对象，其值为 obj 的当前字段值。

```java title='使用反射访问值或设置值'
var harry = new Empolyee("wkq", 50000, 1997, 1, 27);
Class<? extends Empolyee> cl = harry.getClass();
Field f = cl.getDeclaredField("hireDay");
//the name field of the Employee class
Object o = f.get(harry);
System.out.println("o = " + o);  // IllegalAccessException
```

当然，不仅可以获取值，也可以设置值。调用 f.set(obj,value),将把对象 obj 中 f 表示的字段设置为新值。

实际上，这段代码存在一个问题。由于 name 是一个私有字段，所以 get 和 set 方法会抛出一个 IllegalAccessException 。只能对可以访问的字段使用 get 和 set 方法。Java 安全机制允许查看一个对象有那些字段，但是除非是拥有访问权限，否则不允许读写哪些字段的值。

反射机制的默认行为受限于 Java 的访问控制。不过，可以调用 Field、Method 和 Constructor 对象的 setAccessible 方法覆盖 Java 的访问权限。
```java title='使用 setAccessible(true) 覆盖Java的访问权限'
var harry = new Empolyee("wkq", 50000, 1997, 1, 27);
Class<? extends Empolyee> cl = harry.getClass();
Field f = cl.getDeclaredField("hireDay");
//the name field of the Employee class

// highlight-start
f.setAccessible(true);
// highlight-end

Object o = f.get(harry);
System.out.println("o = " + o);
```
setAccessible 方法是 AccessibleObject 类中的一个方法，它 Field 、Method 和 Constructor 类 的公共超类。


```java

```
